﻿/*
 * Twipler - Twitter Web Client with features.
 *  
 *  Copyright (C) 2009, 2010. Ian Quigley
 * 
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details. 
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>. 
 */

using System;
using System.Web;
using System.Web.Caching;
using log4net;
using log4net.Config;
using Twipler.App.Render;
using Twipler.App.Render.Tree;
using Twipler.App.Session;
using Twipler.Twitter;
using Twipler.Data.Entity.Twipler;
using Dimebrain.TweetSharp.Model;
using System.Text;

namespace Twipler.App
{
    public class Current
    {
        public static NHibernate.Cfg.Configuration NHibConfig
        {
            get 
            {
                if (HttpContext.Current == null)
                    return null;

                return (NHibernate.Cfg.Configuration)HttpContext.Current.Application["NHibConfig"]; 
            }
            set 
            { 
                if (HttpContext.Current != null)
                    HttpContext.Current.Application["NHibConfig"] = value; 
            }
        }


        public static Visitor Visitor
        {
            get 
			{
				try
				{
					if (HttpContext.Current == null || HttpContext.Current.Session == null)
						return Visitor.Anonymous;

					return HttpContext.Current.Session["SessionTrack"] == null ? Visitor.Anonymous : ((InnerSession) HttpContext.Current.Session["SessionTrack"]).Visitor;
				}
				catch
				{
					return Visitor.Anonymous;
				}
            }
            set { SessionTrack.Visitor = value; }
        }

        public static PageProducer PageProducer
        {
            get { return HttpContext.Current.Session["PageProducer"] as PageProducer; }
            set { HttpContext.Current.Session["PageProducer"] = value; }
        }

        public static IInnerSession SessionTrack
        {
            get
            {
                IInnerSession thisTrack = HttpContext.Current.Session["SessionTrack"] as InnerSession;
                if (thisTrack == null)
                {
                    thisTrack = InnerSessionFactory.Request(HttpContext.Current.Session.SessionID);
                    HttpContext.Current.Session["SessionTrack"] = thisTrack;
                }

                return thisTrack;
            }
        }

        public static StylesheetProducer StylesheetProducer
        {
            get 
            { 
                StylesheetProducer sheetProducer = HttpContext.Current.Session["StylesheetProducer"] as StylesheetProducer;
                if (sheetProducer == null)
                {
                    sheetProducer = new StylesheetProducer();
                    HttpContext.Current.Session["StylesheetProducer"] = sheetProducer;
                }

                return sheetProducer;
            }
            set 
            {
                HttpContext.Current.Session["StylesheetProducer"] = value; 
            }
        }

        public static int UtcSecondsOffset
        {
            get 
            {
                if (HttpContext.Current.Cache["UtcSecondsOffset"] == null)
                {
                    int offset = (int)UtcSecondsOffsetLowest.TotalSeconds;
                    
                    HttpContext.Current.Cache.Add(
                        "UtcSecondsOffset",
                        offset,
                        null,
                        DateTime.Now.AddMinutes(10),
                        System.Web.Caching.Cache.NoSlidingExpiration,
                        System.Web.Caching.CacheItemPriority.Low,
                        null);
                }

                return (int)HttpContext.Current.Cache["UtcSecondsOffset"];            
            }
        }

        public static TimeSpan UtcSecondsOffsetLowest
        {
            set
            {
                int howOff = (int) value.TotalSeconds < -20000000 ? -20000000 : (int) value.TotalSeconds;

                if (howOff > 3600)
                    howOff = 3600;

                int lowest = 0;
                if (HttpContext.Current.Application["UtcSecondsLowest"] != null)
                    lowest = (int)HttpContext.Current.Application["UtcSecondsLowest"];

                if (howOff < lowest)
                    lowest = howOff;

                HttpContext.Current.Application["UtcSecondsLowest"] = lowest;
            }

            get
            {
                TimeSpan r = TimeSpan.Zero;
                lock (HttpContext.Current)
                {
                    if (HttpContext.Current.Application["UtcSecondsLowest"] != null)
                        r = new TimeSpan(0, 0, 0, (int) HttpContext.Current.Application["UtcSecondsLowest"]);

                    HttpContext.Current.Application["UtcSecondsLowest"] = null;
                }

                return r;
            }
        }
        

        public static string PrivateUniqueSecret
        {
            get 
            { 
                string salt = HttpContext.Current.Session["PrivateUniqueSecret"] as string;
                if (string.IsNullOrEmpty(salt))
                {
                    salt = RandomString(6);
                    HttpContext.Current.Session["PrivateUniqueSecret"] = salt;
                }
                return salt;                
            }
            set { HttpContext.Current.Session["PrivateUniqueSecret"] = value; }
        }

        private static Random _random;
        public static Random Random
        {
            get
            {
                if (_random == null)
                    _random = new Random();

                return _random;
            }
        }

        public static Twipler.Data.Entity.Base EntityEdit
        {
            get { return (Twipler.Data.Entity.Base)HttpContext.Current.Session["EntityEdit"]; }
            set { HttpContext.Current.Session["EntityEdit"] = value; }
        }

        public static int ResultsPerPage
        {
            get { return  HttpContext.Current.Session["ResultsPerPage"] == null ? 25 : (int)HttpContext.Current.Session["ResultsPerPage"]; }
            set { HttpContext.Current.Session["ResultsPerPage"] = value; }
        }


		private static ILog _log = null;

		public static ILog Log
		{
			get
			{
				if (_log == null)
				{
					if (Config.IsLoggingEnabled)
					{
						XmlConfigurator.Configure();
						_log = LogManager.GetLogger(typeof(App.Current));
					}
					else
					{
						_log = new FakeLogger();
					}
				}
				return _log;
			}

			set
			{
				if ((_log != null) && !(_log is FakeLogger))
					LogManager.Shutdown();

				_log = value;
			}
		}

		#region Fake Logger
		public class FakeLogger : ILog
		{
			public void Debug(object message, Exception exception) { }
			public void Debug(object message) { }
			public void DebugFormat(IFormatProvider provider, string format, params object[] args) { }
			public void DebugFormat(string format, object arg0, object arg1, object arg2) { }
			public void DebugFormat(string format, object arg0, object arg1) { }
			public void DebugFormat(string format, object arg0) { }
			public void DebugFormat(string format, params object[] args) { }
			public void Error(object message, Exception exception) { }
			public void Error(object message) { }
			public void ErrorFormat(IFormatProvider provider, string format, params object[] args) { }
			public void ErrorFormat(string format, object arg0, object arg1, object arg2) { }
			public void ErrorFormat(string format, object arg0, object arg1) { }
			public void ErrorFormat(string format, object arg0) { }
			public void ErrorFormat(string format, params object[] args) { }
			public void Fatal(object message, Exception exception) { }
			public void Fatal(object message) { }
			public void FatalFormat(IFormatProvider provider, string format, params object[] args) { }
			public void FatalFormat(string format, object arg0, object arg1, object arg2) { }
			public void FatalFormat(string format, object arg0, object arg1) { }
			public void FatalFormat(string format, object arg0) { }
			public void FatalFormat(string format, params object[] args) { }
			public void Info(object message, Exception exception) { }
			public void Info(object message) { }
			public void InfoFormat(IFormatProvider provider, string format, params object[] args) { }
			public void InfoFormat(string format, object arg0, object arg1, object arg2) { }
			public void InfoFormat(string format, object arg0, object arg1) { }
			public void InfoFormat(string format, object arg0) { }
			public void InfoFormat(string format, params object[] args) { }
			public bool IsDebugEnabled { get { return false; } }
			public bool IsErrorEnabled { get { return false; } }
			public bool IsFatalEnabled { get { return false; } }
			public bool IsInfoEnabled { get { return false; } }
			public bool IsWarnEnabled { get { return false; } }
			public void Warn(object message, Exception exception) { }
			public void Warn(object message) { }
			public void WarnFormat(IFormatProvider provider, string format, params object[] args) { }
			public void WarnFormat(string format, object arg0, object arg1, object arg2) { }
			public void WarnFormat(string format, object arg0, object arg1) { }
			public void WarnFormat(string format, object arg0) { }
			public void WarnFormat(string format, params object[] args) { }
			public log4net.Core.ILogger Logger { get { return null; } }
		}
		#endregion



		public static string RandomString(int length)
        {
            Random r = new Random();
            StringBuilder str = new StringBuilder(length + 4);
            string selectFrom = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

            for (int i = 0; i < length; i++)
                str.Append(selectFrom[r.Next(selectFrom.Length)]);

            return str.ToString();
        }
    }
}